package com.nicho.dao;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import com.nicho.pojo.Course;
import com.nicho.pojo.Student;
import com.nicho.pojo.Teacher;
import com.nicho.util.CloseStream;
import com.nicho.util.MD5;

/*
 * @Author: 姜东浩
 * @Date: 2021-11-11 14:13:34
 * @LastEditors: 姜东浩
 * @LastEditTime: 2021-11-11 14:13:34
 * @Description: 学生数据库操作
 */
public class StudentDAO {

    static Student stu = null;
    ArrayList<Student> stuList = null;
    ArrayList<Teacher> teacherList = null;
    ArrayList<Course> courseList = null;
    static File studentData = new File("src/com/nicho/file/StudentData.txt");
    static File courseData = new File("src/com/nicho/file/CourseData.txt");
    static File teacherData = new File("src/com/nicho/file/TeacherData.txt");

    /**
     * @description: 学生登录
     * @param {Student} student
     * @return 登陆成功返回学生对象，失败返回null
     * @author: 姜东浩
     */
    public Student studentLogin(Student student) {

        ObjectInputStream ois = null;
        // 如果存学生的文件不为空，则反序列化，否则返回null
        try {
            if (studentData.length() > 0) {
                ois = new ObjectInputStream(new FileInputStream(studentData));
                stuList = (ArrayList<Student>) ois.readObject();
            } else {
                System.out.println("文件为空");
                return null;
            }
            // 遍历学生列表，找到这个学生账号对应的学生，退出循环
            for (int i = 0; i < stuList.size(); i++) {
                if (stuList.get(i).getStudentId().equals(student.getStudentId())) {
                    stu = stuList.get(i);
                    break;
                }
            }
            // 如果stu是null直接返回null
            if (stu == null) {
                return null;
            }
            // 如果传进来的账号密码与文件中保存的账号密码相等，则返回学生对象，否则返回null
            if (student.getStudentId().equals(stu.getStudentId())
                    && MD5.md5(student.getPassword()).equals(stu.getPassword())) {
                return stu;
            } else {
                stu = null;
                return null;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            CloseStream.closeObjectInputStream(ois);
        }

    }

    /**
     * @description: 修改自己的密码
     * @param {String} newPassword
     * @return 修改成功返回1，修改失败或有异常返回-1
     * @author: 姜东浩
     */
    public int updatePassword(String newPassword) {

        ObjectInputStream ois = null;
        ObjectOutputStream oos = null;
        // 如果存学生的文件不为空，则反序列化后传给stuList，否则返回-1
        try {
            if (studentData.length() > 0) {
                ois = new ObjectInputStream(new FileInputStream(studentData));
                stuList = (ArrayList<Student>) ois.readObject();
            } else {
                return -1;
            }
            // 遍历学生列表，找到后修改密码，再把更新完的List序列化到数据库，返回1，没找到返回-1
            for (int i = 0; i < stuList.size(); i++) {
                if (stuList.get(i).getStudentId().equals(stu.getStudentId())) {
                    stuList.get(i).setPassword(newPassword);
                    oos = new ObjectOutputStream(new FileOutputStream(studentData));
                    oos.reset();
                    oos.writeObject(stuList);
                    return 1;
                }
            }
            return -1;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return -1;
        } catch (IOException e) {
            e.printStackTrace();
            return -1;
        } finally {
            CloseStream.closeObjectStream(ois, oos);
        }

    }

    /**
     * @description: 遍历课程表集合，返回可选课程的Map
     * @return 返回选课Map<课程编号，课程余量>
     * @author: 姜东浩
     */
    public Map<String, Integer> chooseCourseMap() {

        ObjectInputStream ois = null;
        Map<String, Integer> courseMap = new HashMap<>();
        // 如果存课程的文件不为空，则反序列化后传给coueList，否则返回new HashMap<>()
        try {
            if (courseData.length() > 0) {
                ois = new ObjectInputStream(new FileInputStream(courseData));
                courseList = (ArrayList<Course>) ois.readObject();
            } else {
                return courseMap;
            }
            for (int i = 0; i < courseList.size(); i++) {
                String coutseId = courseList.get(i).getCourseId();
                int remainderNum = courseList.get(i).getSnum() - courseList.get(i).getCnum();
                Teacher cteacher = courseList.get(i).getcTeacher();

                if (remainderNum > 0 && cteacher != null) {
                    courseMap.put(coutseId, remainderNum);
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            CloseStream.closeObjectInputStream(ois);
        }
        return courseMap;
    }

    /**
     * @description: 打印一个Map
     * @param {Map<String,Integer>} map
     * @author: 姜东浩
     */
    public void printMap(Map<String, Integer> map) {

        Set<Map.Entry<String, Integer>> es = map.entrySet();
        Iterator<Map.Entry<String, Integer>> it = es.iterator();
        while (it.hasNext()) {
            // 返回的是封装了key和value对象的Map.Entry对象
            Map.Entry<String, Integer> en = it.next();
            // 获取Map.Entry对象中封装的key和value对象
            String key = en.getKey();
            Integer value = en.getValue();
            System.out.println("课程编号：" + key + "\t" + " 课程余量：" + value);
        }

    }

    /**
     * @description: 通过key获取value
     * @param {Map<String,Integer>} map
     * @param {String}              key
     * @return 有此key返回它的value，否则返回-1
     * @author: 姜东浩
     */
    public int getMapValue(Map<String, Integer> map, String key) {

        // 判断又没有这个key，有取它的值后返回1，没有返回-1
        if (map.get(key) != null) {
            return (map.get(key));
        } else {
            return -1;
        }

    }

    /**
     * @description: 通过课程编号判断是否有此课程
     * @param {String} courseId
     * @return 有返回课程对象，没有返回null
     * @author: 姜东浩
     */
    public Course existCourseById(String courseId) {

        ObjectInputStream ois = null;
        // 如果存课程的文件不为空，则反序列化后传给courseList，否则返回null
        try {
            if (courseData.length() > 0) {
                ois = new ObjectInputStream(new FileInputStream(courseData));
                courseList = (ArrayList<Course>) ois.readObject();
            } else {
                return null;
            }
            // 遍历List，找到后返回对象，否则返回null
            for (int i = 0; i < courseList.size(); i++) {
                if (courseList.get(i).getCourseId().equals(courseId)) {
                    return courseList.get(i);
                }
            }
            return null;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            CloseStream.closeObjectInputStream(ois);
        }

    }

    /**
     * @description: 将选此课程的人数加一
     * @param {String} courseId
     * @return 加一操作成功返回1，失败返回-1
     * @author: 姜东浩
     */
    public int plusCourseCNum(String courseId) {

        ObjectInputStream ois = null;
        ObjectOutputStream oos = null;
        // 如果存课程的文件不为空，则反序列化后传给courseList，否则返回-1
        try {
            if (courseData.length() > 0) {
                ois = new ObjectInputStream(new FileInputStream(courseData));
                courseList = (ArrayList<Course>) ois.readObject();
            } else {
                return -1;
            }
            // 遍历List，找到后进行加一操作，操作成功返回1
            for (int i = 0; i < courseList.size(); i++) {
                if (courseList.get(i).getCourseId().equals(courseId)) {
                    courseList.get(i).setCnum(courseList.get(i).getCnum() + 1);
                    oos = new ObjectOutputStream(new FileOutputStream(courseData));
                    oos.reset();
                    oos.writeObject(courseList);
                    return 1;
                }
            }
            return -1;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return -1;
        } catch (IOException e) {
            e.printStackTrace();
            return -1;
        } finally {
            CloseStream.closeObjectStream(ois, oos);
        }

    }

    /**
     * @description: 将选此课程的人数减一
     * @param {String} courseId
     * @return 减一操作成功返回1，失败返回-1
     * @author: 姜东浩
     */
    public int subtractCourseCNum(String courseId) {

        ObjectInputStream ois = null;
        ObjectOutputStream oos = null;
        // 如果存课程的文件不为空，则反序列化后传给courseList，否则返回-1
        try {
            if (courseData.length() > 0) {
                ois = new ObjectInputStream(new FileInputStream(courseData));
                courseList = (ArrayList<Course>) ois.readObject();
            } else {
                return -1;
            }
            // 遍历List，找到后进行减一操作，操作成功返回1
            for (int i = 0; i < courseList.size(); i++) {
                if (courseList.get(i).getCourseId().equals(courseId)) {
                    courseList.get(i).setCnum(courseList.get(i).getCnum() - 1);
                    oos = new ObjectOutputStream(new FileOutputStream(courseData));
                    oos.reset();
                    oos.writeObject(courseList);
                    return 1;
                }
            }
            return -1;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return -1;
        } catch (IOException e) {
            e.printStackTrace();
            return -1;
        } finally {
            CloseStream.closeObjectStream(ois, oos);
        }

    }

    /**
     * @description: 向自己的课程列表添加一门课程
     * @param {Course} course
     * @return 添加课程成功返回1，失败返回-1
     * @author: 姜东浩
     */
    public int addCourseInAStuList(Course course) {

        ObjectInputStream ois = null;
        ObjectOutputStream oos = null;
        // 如果存学生的文件不为空，则反序列化后传给stuList，否则返回-1
        try {
            if (studentData.length() > 0) {
                ois = new ObjectInputStream(new FileInputStream(studentData));
                stuList = (ArrayList<Student>) ois.readObject();
            } else {
                return -1;
            }
            // 遍历学生列表，找到后添加课程，再把更新完的List序列化到数据库，返回1，没找到返回-1
            for (int i = 0; i < stuList.size(); i++) {
                if (stuList.get(i).getStudentId().equals(stu.getStudentId())) {
                    stuList.get(i).getsCourseList().add(course);
                    oos = new ObjectOutputStream(new FileOutputStream(studentData));
                    oos.reset();
                    oos.writeObject(stuList);
                    return 1;
                }
            }
            return -1;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return -1;
        } catch (IOException e) {
            e.printStackTrace();
            return -1;
        } finally {
            CloseStream.closeObjectStream(ois, oos);
        }

    }

    /**
     * @description: 向自己的课程列表移除一门课程
     * @param {Course} course
     * @return 移除课程成功返回1，失败返回-1
     * @author: 姜东浩
     */
    public int removeCourseInAStuList(Course course) {

        ObjectInputStream ois = null;
        ObjectOutputStream oos = null;
        // 如果存学生的文件不为空，则反序列化后传给stuList，否则返回-1
        try {
            if (studentData.length() > 0) {
                ois = new ObjectInputStream(new FileInputStream(studentData));
                stuList = (ArrayList<Student>) ois.readObject();
            } else {
                return -1;
            }
            // 遍历学生列表，找到后移除课程，再把更新完的List序列化到数据库，返回1，没找到返回-1
            for (int i = 0; i < stuList.size(); i++) {
                if (stuList.get(i).getStudentId().equals(stu.getStudentId())) {
                    for(int j = 0;j<stuList.get(i).getsCourseList().size(); j++){
                        if(stuList.get(i).getsCourseList().get(j).getCourseId().equals(course.getCourseId())){
                            stuList.get(i).getsCourseList().remove(j);
                            oos = new ObjectOutputStream(new FileOutputStream(studentData));
                            oos.reset();
                            oos.writeObject(stuList);
                            return 1;
                        } 
                    }
                    
                }
            }
            return -1;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return -1;
        } catch (IOException e) {
            e.printStackTrace();
            return -1;
        } finally {
            CloseStream.closeObjectStream(ois, oos);
        }

    }

    /**
     * @description: （把我加到教我的老师管理的学生列表）将我添加到我这门课的讲师的学生列表中
     * @param {Course} course
     * @return 添加成功返回1，没找到此教师返回-1，抛出异常返回-3
     * @author: 姜东浩
     */
    public int addMeToTeaList(Course course) {

        ObjectInputStream ois = null;
        ObjectOutputStream oos = null;
        // 如果存教师的文件不为空，则反序列化后传给teacherList，否则返回-1
        try {
            if (teacherData.length() > 0) {
                ois = new ObjectInputStream(new FileInputStream(teacherData));
                teacherList = (ArrayList<Teacher>) ois.readObject();
            } else {
                return -1;
            }

            for (int i = 0; i < teacherList.size(); i++) {
                if (teacherList.get(i).getTeacherId().equals(course.getcTeacher().getTeacherId())) {
                    teacherList.get(i).getStudentList().add(stu);
                    oos = new ObjectOutputStream(new FileOutputStream(teacherData));
                    oos.reset();
                    oos.writeObject(teacherList);
                    return 1;
                }
            }
            return -1;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return -3;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return -3;
        } catch (IOException e) {
            e.printStackTrace();
            return -3;
        } finally {
            CloseStream.closeObjectStream(ois, oos);
        }

    }

    /**
     * @description: （把我在教我的老师的管理的学生列表中移除）将我到在这门课的讲师的学生列表中移除
     * @param {Course} course
     * @return 移除成功返回1，没找到此教师返回-1，抛出异常返回-3
     * @author: 姜东浩
     */
    public int removeMeToTeaList(Course course) {

        ObjectInputStream ois = null;
        ObjectOutputStream oos = null;
        // 如果存教师的文件不为空，则反序列化后传给teacherList，否则返回-1
        try {
            if (teacherData.length() > 0) {
                ois = new ObjectInputStream(new FileInputStream(teacherData));
                teacherList = (ArrayList<Teacher>) ois.readObject();
            } else {
                return -1;
            }

            for (int i = 0; i < teacherList.size(); i++) {
                if (teacherList.get(i).getTeacherId().equals(course.getcTeacher().getTeacherId())) {
                    for(int j=0;j<teacherList.get(i).getStudentList().size(); j++){
                        if(teacherList.get(i).getStudentList().get(j).getStudentId().equals(stu.getStudentId())){
                            teacherList.get(i).getStudentList().remove(j);
                            oos = new ObjectOutputStream(new FileOutputStream(teacherData));
                            oos.reset();
                            oos.writeObject(teacherList);
                            return 1;
                        }
                    }
                    
                }
            }
            return -1;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return -3;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return -3;
        } catch (IOException e) {
            e.printStackTrace();
            return -3;
        } finally {
            CloseStream.closeObjectStream(ois, oos);
        }

    }

    /**
     * @description: 获得自己选的全部课程集合
     * @return 返回自己选的全部课程
     * @author: 姜东浩
     */
    public ArrayList<Course> getMyCourseList() {

        ObjectInputStream ois = null;
        // 如果存学生的文件不为空，则反序列化后传给stuList，否则返回-1
        try {
            if (studentData.length() > 0) {
                ois = new ObjectInputStream(new FileInputStream(studentData));
                stuList = (ArrayList<Student>) ois.readObject();
            } else {
                return null;
            }
            // 遍历学生列表，找到后返回此学生所选课程的List
            for (int i = 0; i < stuList.size(); i++) {
                if (stuList.get(i).getStudentId().equals(stu.getStudentId())) {
                    return stuList.get(i).getsCourseList();
                }
            }
            return null;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            CloseStream.closeObjectInputStream(ois);
        }

    }

    /**
     * @description: （简单打印）打印自己的选课集合
     * @param {ArrayList<Course>} myCourseList
     * @author: 姜东浩
     */
    public void printMyCourseList(ArrayList<Course> myCourseList) {

        for (Course c : myCourseList) {
            System.out.println("课程编号：" + c.getCourseId() + "\t" + "课程名称：" + c.getCourseName() + "\t" + "授课教师：" + c.getcTeacher().getTeacherName());
        }

    }

    /**
     * @description: （全部打印）打印自己的选课集合
     * @param {ArrayList<Course>} myCourseList
     * @author: 姜东浩
     */
    public void printMyCourseListAM(ArrayList<Course> myCourseList) {

        myCourseList.forEach(System.out::println);

    }

    /**
     * @description: 判断自己是否选了这门课
     * @param {String} courseId
     * @return 自己选了这门课返回1，没选返回-1
     * @author: 姜东浩
     */
    public int hadThisCourse(String courseId) {

        ObjectInputStream ois = null;
        // 如果存学生的文件不为空，则反序列化后传给stuList，否则返回-1
        try {
            if (studentData.length() > 0) {
                ois = new ObjectInputStream(new FileInputStream(studentData));
                stuList = (ArrayList<Student>) ois.readObject();
            } else {
                return -1;
            }
            for (int i = 0; i < stuList.size(); i++) {
                if (stuList.get(i).getStudentId().equals(stu.getStudentId())) {
                    for (int j = 0; j < stuList.get(i).getsCourseList().size(); j++) {
                        if (stuList.get(i).getsCourseList().get(j).getCourseId().equals(courseId)) {
                            return 1;
                        }
                    }
                }

            }
            return -1;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return -1;
        } catch (IOException e) {
            e.printStackTrace();
            return -1;
        } finally {
            CloseStream.closeObjectInputStream(ois);
        }

    }

}